feat(studio): share native audio and upscale commands - #280
Conversation
…red-audio-tool-commands # Conflicts: # app/services/image_generation_commands.py
…red-audio-tool-commands
# Conflicts: # app/services/image_generation_commands.py
PR Review — Loreframe StudioRisk: medium Automated review from Findings
Changed files
CONTRIBUTING checklist
Posted by the repo PR review workflow. Re-runs on each push to the PR. |
Code healthQuality score: 58.6/100Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.
Change vs PR base: +1.5 points.
Markdown, JSON catalogs and tests are out of this table. Only Most complex functions
Trend vs baseline
Warnings
Ratchet passed. |
# Conflicts: # ui/src/i18n/locales/en/studio.json # ui/src/i18n/locales/es/studio.json
Wizard queue_sfx_pack reused one capability commandId as every clip's generation.sfx intent_id. Distinct prompts then 409'd after the first clip; identical prompts silently replayed the first receipt. Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
Studio SFX owns MMAudio_prompt. Audio sub-tabs share one params map, so Speech or Music lyrics stayed in prompt. startGeneration used MMAudio_prompt ?? prompt, and the closed command accepted that leftover as the sound description. An empty SFX box then generated the previous script. Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
Switching SFX → Speech/Music left params.video_guide in the shared form. generation.music then rejected the leftover guide as an active residual, and generation.speech rejected the URL against its empty-only catalog enum. Stash the guide with the SFX tab, treat a blank residual as inactive, and do not force '' onto audio Load Settings after the tab-owned restore. Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
SFX escribe MMAudio_prompt y sfx_text_weight en el formulario compartido. Al pasar a Speech o Music, generation.speech rechazaba el prompt activo y generation.music rechazaba el peso desconocido. El adaptador del formulario los descarta; el envelope cerrado de MCP sigue fallando en cerrado. Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
# Conflicts: # ui/tests/studioAudioReferenceState.test.ts
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_98557ac1-cc70-472b-baa1-0f0975fdfbf7) |
What changes
Studio speech, music, SFX and Tools upscale use the same durable operations as external MCP clients. Wizard displays the exact command before admission; recovery retains its intention, receipt and native task. A deliberate new intention creates another job.
Music preserves literal lyrics, caption and description. ACE-Step accepts an omitted caption; MiniMax Music 3 requires it before admission. SFX supports text-only MMAudio and canonical video guides. Stale video-model options no longer alter SFX durations. Admission validates installed dependencies and resource identity; SFX rechecks them before model work.
SFX packs use distinct, stable per-clip intentions and preserve every admitted receipt, including partial failures or failed navigation. Explicit authored JSON clips and negative prompts survive missing or rewritten LLM actions; an incomplete pack cannot fall through to video generation. The server recovers each admitted clip; browser-independent pack scheduling remains P9 work.
This draft incorporates development
d88c85d5, rechecked by fetch. Published candidate:b18b4441. PRs #284, #285, #286, #287 and #288 were integrated locally and hardened in this branch. The draft has not been merged into development, and main has not been published.Audio references are isolated by sub-tab and restored with their displayed filenames. Loading saved settings retains the previous tab's references. Speech voice counts cannot discard newly selected Music references, rename voices from lyrics or overwrite Music selectors. Entering Audio selects the tab matching the restored model; late defaults cannot disable a restored reference. A selected voice file is visible and removable without deleting its speaker.
Load Settings restores SFX descriptions, negatives, zero-valued controls and recorded audio duration. An empty SFX box cannot submit leftover Speech/Music text; direct MCP prompt-only commands remain valid. Gallery restore/reroll capture the clicked filename and workspace; newer requests and workspace changes invalidate old responses. Generate shows preparation rather than optimistic queue acceptance, guards rapid duplicate clicks, and excludes failed placeholders from its active count.
SFX video guides now leave the active form when switching to Speech/Music and return with SFX. Its description, negative prompt and strength cannot block either other tab. A real browser pass also exposed a Music → Speech failure on hidden
alt_guidance_scale; the form projection now removes that music-only field andlyrics_language. Direct command envelopes retain their closed validation. Audio admission guards share one snapshot definition with tab-specific controls.Validation
b18b4441PASS (run34405517373): 3,022 Python passed, 9 skipped; UI checks, Chromium boot and Windows Speech export E2E pass. Independent QA is neutral, not independent approval. Luna workers exhausted their quota; independent review of new changes remains pending.b18b4441: 1,441 UI tests pass, ESLint, TypeScript, i18n, build and code-health ratchet against development pass. Entry JS gzip: 324,680/327,680 B. Production LOC +8,223 against a budget of 8,229; no baseline or budget increases. A previous candidate exceeded that LOC budget; repeated typed-submit error blocks were consolidated and unreachable button branches removed, with tests retained.b18b4441: PASS, one real video upload and SFX → Music → Speech → SFX. Three typed requests preserve authored text, omit foreign controls and restore the original SFX guide. Requests were intercepted with an explicit 422 before server admission: zero new jobs/inferences. The first pass on3c9b failed on the hidden Music control and remains recorded as FAIL; the corrected pass is separate. Public screenshots explain the deliberate rejection messages.5cb8107c: one file upload, Speech → Music → SFX → Speech restores the exact voice/file/selector. No generation was performed for this form test. Earlier browser failures exposed a wrong initial tab/model and a late-defaults selector reset; harness navigation/upload mistakes are recorded separately. Screenshots and results are published.94ab0068: one Wizard request, two V2 admissions, distinct stable child intentions and two native MMAudio WAVs, each 1.022 s / 44.1 kHz mono. Native processing: 38.35 s and 126.16 s. Both official MCP replays retain their original receipts and one task per intention; zero active jobs afterward. Full decode, audible Chromium playback and UI download pass, with matching native/MCP/UI/LAN hashes.Remaining work
P5 still has remaining Studio/Tools modalities. P6–P10 are unfinished, including browser-independent editorial workflows and Video3D export. Reference drafts persist for the browser session; full prompt/caption/duration stashing and cross-reload drafts remain outside this change. SFX can still display a 20 s slider while retaining an invalid larger duration (the command rejects it); a restored guide may display a legacy path until submission canonicalizes it. PR283's count-based deletion heuristic was not integrated because it can erase a newly selected Music reference. H3 processor reference arrays retain a native scalar-settings limitation.
Evidence:
outputs/wizard-mcp-execution-20260909/. Samples and screenshots: http://192.168.1.87:4192/wizard-mcp-20260909/ . SFX pack: http://192.168.1.87:4192/wizard-mcp-20260909/sfx/#pack . Audio UI regression: http://192.168.1.87:4192/wizard-mcp-20260909/audio-reference-fixes/ .PR281 navigation/styles are preserved. The only shared-file compatibility change in VideoInfoBar is wrapping two onClick callbacks so React events cannot be mistaken for an optional output source; its hunks are separate from PR281.
Current form-fix report and screenshots: http://192.168.1.87:4192/wizard-mcp-20260909/sfx-form-fixes/ . All five report files returnHTTP200 and match local hashes.
Audio guide report and screenshots: http://192.168.1.87:4192/wizard-mcp-20260909/audio-guide-fixes/ . Seven report files return HTTP200 with matching hashes.
Note
Medium Risk
Large change to admission, recovery, and queue dispatch across audio/tools paths; incorrect adapter or recovery matching could mis-route jobs or reject valid recoveries.
Overview
Extends the existing image generation command stack into a pluggable native generation facade so Studio speech, music, SFX, and Tools upscale share the same durable intent → receipt → task → FIFO path as MCP/Wizard clients.
ImageGenerationCommandsnow registersNativeGenerationOperationadapters (generation.speech,generation.music,generation.sfx,tools.upscale) with per-operation freeze/prepare/catalog, operation-aware replay fingerprints, andnative_workerso recovery/dispatch only runs tool workers when provenance matches a canonical admission. HTTP/MCP discovery merges adapter catalogs; reference resolution acceptsmedia_kindfor audio/video.Each modality adds a closed v2 spec (Pydantic freeze + fingerprint), preparation (model/install checks, no queue side effects), and resource inspection (speech/music audio refs, SFX video guides + MMAudio file sets). Generation input prep honors
prepared_studio_speech/prepared_studio_audiofor admitted audio params.Runtime hooks: deferred prep consults
native_workerfirst; legacy tools upscale canadmit_generation_commandastools.upscale. SFX usesprepared_sfx_executionto re-verify receipt, params, and guide identity before inference—skipping legacy MMAudio downloads for typed jobs and failing closed on missing/changed guides instead of silent text-only fallback.Reviewed by Cursor Bugbot for commit b18b444. Configure here.